require 'digest/sha1'

class Cartasur::User < User
  establish_connection "cartasur_#{Rails.env}"

  include Authentication
  include Authentication::ByPassword
  include Authentication::ByCookieToken

  has_many :protocols, :class_name => 'Cartasur::Protocol', :foreign_key => 'users_id'
  has_many :objectives, :through => :protocols, :class_name => 'Cartasur::Objective'
  has_many :tracks, :class_name => 'Cartasur::Track'
  has_many :measures, :class_name =>  'Cartasur::Measure'

  #forum
  has_many :posts, :class_name =>  'Cartasur::Post'
  has_many :topics, :class_name =>  'Cartasur::Topic'
  #uploads
  has_many :uploads, :class_name => 'Cartasur::UserUpload'
  accepts_nested_attributes_for :uploads, :allow_destroy => true

  #image
  mount_uploader :image_url, CartasurImageUploader

  attr_accessible :login, :id, :email, :email2, :surname, :other_names, :date_of_birth, :gender, :uploads_attributes

  validates :email2, :presence   => true,
            :uniqueness => true,
            :format     => { :with => Authentication.email_regex, :message => Authentication.bad_email_message },
            :length     => { :within => 6..100 }

  def self.authenticate(login, password)
    return nil if login.blank? || password.blank?
    u = where(['login = ?', login]).first # need to get the salt
    u && u.authenticated?(password) ? u : nil
  end

  def login=(value)
    write_attribute :login, (value ? value.downcase : nil)
  end

  #def name_with_initial
  #  "#{first_name.first}. #{last_name}"
  #end

  def user_protocols
    Cartasur::Objective.joins(:protocols).where("protocols.users_id = #{self.id}")
  end

  #gets all protocols (objetives ) a user has, with a field nt_visited to
  #denote whether it is completed or not
  def all_protocols
    objectives_to_return = []
    begin
      #get all protocols
      @all_protocols = Cartasur::Protocol.where(:users_id => self.id).order(:objective_id)
      #and all visited ones, if any
      @visiteds = Cartasur::Visited.where(:user_id => self.id)

      @visiteds_objective_ids = @visiteds.map(&:objective_id)
      #distinguish the visiteds from the pendings
      objectives_to_return = @all_protocols.map do |protocol|
        if  @visiteds_objective_ids.include?(protocol.objective_id)
          protocol[:nt_visited] = true

        else
          protocol[:nt_visited] = false

        end
        # fix for August objectives. TODO: remove this later
        if self.login != "cartasur60" and self.login.starts_with? "cartasur6"
          if protocol.objective.months.include? "7,9"
            protocol.objective.months.sub!("7,9", "7,8,9")

          end
        end
        {protocol: protocol, objective: protocol.objective}  unless protocol.nil?
      end
    rescue Exception => e
      logger.error  "Error when retrieving user #{self.login} all objectives " << e.message
    end
    objectives_to_return
  end

  #simplistic method to get completed protocols - the best way is to cross-check
  # users protocols with visiteds table's protocol ids
  def completed_protocols
    objectives_to_return = []
    begin
      #get all protocols
      @all_protocols = Cartasur::Protocol.where(:users_id => self.id).order(:objective_id)
      #and all visited ones, if any
      @visiteds = Cartasur::Visited.where(:user_id => self.id)

      @visiteds_objective_ids = @visiteds.map(&:objective_id)
      #distinguish the visiteds from the pendings
      objectives_to_return = @all_protocols.collect do |protocol|
        vis = @visiteds.where(:protocol_id => protocol.id).first
        unless  vis.blank?
          # fix for August objectives. TODO: remove this later
          if self.login != "cartasur60" and self.login.starts_with? "cartasur6"
            if protocol.objective.months.include? "7,9"
              protocol.objective.months.sub!("7,9", "7,8,9")

            end
          end
          protocol[:nt_visited] = true
          {protocol: protocol, objective: protocol.objective, visited: vis}  unless protocol.nil?
        end

      end
    rescue Exception => e

      logger.error  "ERROR: Error when retrieving user #{self.login} completed objectives " << e.message
    end
    objectives_to_return.reject!(&:blank?)
  end

  #simplistic method to get completed protocols - the best way is to cross-check
  # users protocols with visiteds table's protocol ids
  def incomplete_protocols
    objectives_to_return = []
    begin
      #get all protocols
      @all_protocols = Cartasur::Protocol.where(:users_id => self.id).order(:objective_id)
      #and all visited ones, if any
      @visiteds = Cartasur::Visited.where(:user_id => self.id)

      @visiteds_objective_ids = @visiteds.map(&:objective_id)
      #distinguish the visiteds from the pendings
      objectives_to_return = @all_protocols.collect do |protocol|
        unless  @visiteds_objective_ids.include?(protocol.objective_id)
          # fix for August objectives. TODO: remove this later
          if self.login != "cartasur60" and self.login.starts_with? "cartasur6"
            if protocol.objective.months.include? "7,9"
              protocol.objective.months.sub!("7,9", "7,8,9")

            end
          end
          protocol[:nt_visited] = false
          {protocol: protocol, objective: protocol.objective}  unless protocol.nil?
        end

      end
    rescue Exception => e
      logger.error  "Error when retrieving user #{self.login} completed objectives " << e.message
    end
    objectives_to_return.reject(&:blank?)
  end

  #all protocols, but with visiteds objects that have been finished
  def all_protocols_plus_info
    objectives_to_return = []
    begin
      #get all protocols
      @all_protocols = Cartasur::Protocol.where(:users_id => self.id).order(:objective_id)
      #and all visited ones, if any
      @visiteds = Cartasur::Visited.where(:user_id => self.id)

      @visiteds_objective_ids = @visiteds.map(&:objective_id)
      #distinguish the visiteds from the pendings
      objectives_to_return = @all_protocols.collect do |protocol|
        vis = @visiteds.where(:protocol_id => protocol.id).first

        # fix for August objectives. TODO: remove this later
        if self.login != "cartasur60" and self.login.starts_with? "cartasur6"
          if protocol.objective.months.include? "7,9"
            protocol.objective.months.sub!("7,9", "7,8,9")

          end
        end

        if vis.blank?
          protocol[:nt_visited] = false
          {protocol: protocol, objective: protocol.objective} unless protocol.nil?
        else
          protocol[:nt_visited] = true
          {protocol: protocol, objective: protocol.objective, visited: vis} unless protocol.nil?
        end

      end
    rescue Exception => e

      logger.error  "ERROR: Error when retrieving user #{self.login} completed objectives " << e.message
    end
    objectives_to_return.reject(&:blank?)
  end

  #get all his questionnaire answers
  def questionnaire_answers

    Cartasur::Answer.where(:answer_type => "qn_usr_"<<self.id.to_s)

  end
end
